/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.franmontiel.persistentcookiejar;

import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;

import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;

import okhttp3.Cookie;
import okhttp3.HttpUrl;

import java.util.Collections;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * This class is used to test different-2 test cases based on the requirement like get updated cookie,
 * load cookie from different domain, update new cookie over old one, etc
 */
public class PersistentCookieJarTest {
    private PersistentCookieJar persistentCookieJar;
    private HttpUrl url = HttpUrl.parse("https://domain.com/");

    /**
     * This method is used to create instance of persistentCookieJar to perform different-2 test cases
     */
    @Before
    public void createCookieJar() {
        persistentCookieJar = new PersistentCookieJar(
                new SetCookieCache(),
                new SharedPrefsCookiePersistor(AbilityDelegatorRegistry.getAbilityDelegator().getAppContext())
        );
    }

    /**
     * Test that the cookie is stored and also loaded when the a matching url is given
     */
    @Test
    public void regularCookie() {
        Cookie cookie = TestCookieCreator.createPersistentCookie(false);
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(cookie));
        List<Cookie> storedCookies = persistentCookieJar.loadForRequest(url);
        assertEquals(cookie, storedCookies.get(0));
    }

    /**
     * Test that a stored cookie is not loaded for a non matching url.
     */
    @Test
    public void differentUrlRequest() {
        Cookie cookie = TestCookieCreator.createPersistentCookie(false);
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(cookie));
        List<Cookie> storedCookies = persistentCookieJar.loadForRequest(HttpUrl.parse("https://otherdomain.com"));
        assertTrue(storedCookies.isEmpty());
    }

    /**
     * Test that when receiving a cookie equal(cookie-name, domain-value, and path-value)
     * to one that is already stored then the old cookie is overwritten by the new one.
     */
    @Test
    public void updateCookie() {
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(
                TestCookieCreator.createPersistentCookie("name", "first")));
        Cookie newCookie = TestCookieCreator.createPersistentCookie("name", "last");
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(newCookie));
        List<Cookie> storedCookies = persistentCookieJar.loadForRequest(url);
        assertTrue(storedCookies.size() == 1);
        assertEquals(newCookie, storedCookies.get(0));
    }

    /**
     * Test that a expired cookie is not retrieved
     */
    @Test
    public void expiredCookie() {
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(
                TestCookieCreator.createExpiredCookie()));
        List<Cookie> cookies = persistentCookieJar.loadForRequest(url);
        assertTrue(cookies.isEmpty());
    }

    /**
     * Test that when receiving an expired cookie equal(cookie-name, domain-value, and
     * path-value) to one that is already stored then the old cookie is overwritten by
     * the new one.
     */
    @Test
    public void removeCookieWithExpiredOne() {
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(
                TestCookieCreator.createPersistentCookie(false)));
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(
                TestCookieCreator.createExpiredCookie()));
        assertTrue(persistentCookieJar.loadForRequest(url).isEmpty());
    }

    /**
     * Test that the session cookies are cleared without affecting to the persisted cookies
     */
    @Test
    public void clearSessionCookies() {
        Cookie persistentCookie = TestCookieCreator.createPersistentCookie(false);
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(persistentCookie));
        persistentCookieJar.saveFromResponse(url, Collections.singletonList(
                TestCookieCreator.createNonPersistentCookie()));
        persistentCookieJar.clearSession();
        assertTrue(persistentCookieJar.loadForRequest(url).size() == 1);
        assertEquals(persistentCookieJar.loadForRequest(url).get(0), persistentCookie);
    }

    /**
     * This method is used to clear persistentCookieJar, once the test case will be executed
     */
    @After
    public void cleanCookieJar() {
        persistentCookieJar.clear();
    }
}